import download from "download-git-repo";
import inquirer from "inquirer";
import { exec } from "child_process";
import fs from "node:fs";
import ora from "ora";

const modulesObj = {
    typescript: "^5.0.4",
    "vue-router": "^4.1.6",
    vuex: "^3.1.0",
    pinia: "^2.0.34",
};
let dependenciesList = [];
let devDependenciesList = [];
let inputProjectName = "";
let vueVersionFlag = true; // true表示选择了vue3; false表示选择了vue2

// 判断创建的文件是否已存在当前文件夹中
const isExist = (path) => {
    return fs.existsSync(path);
};
// 封装命令
const execCommand = (command, options, type) => {
    return new Promise((resolve, reject) => {
        // 开启子进程执行命令
        const childProcess = exec(command, options, (error, stdout, stderr) => {
            if (error) {
                reject({
                    errorReason: error,
                    errorType: type,
                });
            }
            // resolve({ stdout, stderr });
            resolve(stdout);
        });
        childProcess.stdout.pipe(process.stdout);
    });
};

// 命令列表
const queryProjectName = (name) => {
    inquirer
        .prompt([
            {
                type: "input",
                name: "name",
                message: "请输入项目名称",
                default: name,
                validate: (input) => {
                    return input ? true : "项目名称不能为空";
                },
            },
        ])
        .then((result) => {
            const { name } = result;
            if (isExist(`./${name}`)) {
                console.log("项目名称已存在，请重新输入");
                queryProjectName(name);
            } else {
                inputProjectName = name;
                // 重置模块选择
                dependenciesList = [];
                devDependenciesList = [];
                queryVue();
            }
        })
        .catch((err) => {});
};
const queryVue = () => {
    inquirer
        .prompt([
            {
                type: "list",
                name: "vueVersion",
                message: "请选择vue版本",
                default: "vue3",
                choices: ["vue2", "vue3"],
            },
        ])
        .then((result) => {
            const { vueVersion } = result;
            vueVersionFlag = vueVersion === "vue3" ? true : false;
            queryTs();
        });
};
const queryTs = () => {
    inquirer
        .prompt([
            {
                type: "confirm",
                name: "isTs",
                message: "是否使用typescript",
                default: false,
            },
            {
                type: "confirm",
                name: "isVueRouter",
                message: "是否使用vue-router",
                default: false,
            },
        ])
        .then((result) => {
            const { isTs, isVueRouter } = result;
            if (isTs) {
                devDependenciesList.push("typescript");
            }
            if (isVueRouter) {
                dependenciesList.push("vue-router");
            }
            queryStore();
        })
        .catch((err) => {});
};
const queryStore = () => {
    inquirer
        .prompt([
            {
                type: "confirm",
                name: "isStore",
                message: "是否使用vuex/pinia",
                default: false,
            },
        ])
        .then((result) => {
            const { isStore } = result;
            if (isStore) {
                queryVuex();
            } else {
                cloneProject();
            }
        })
        .catch((err) => {});
};
const queryVuex = () => {
    const title = "vuex/pinia";
    inquirer
        .prompt([
            {
                type: "list",
                name: title,
                // message: "是否使用vuex(默认“No”)",
                // default: false,
                choices: ["vuex", "pinia"],
            },
        ])
        .then((result) => {
            const choice = result[title];
            dependenciesList.push(choice);
            cloneProject();
        });
};
// 读取并修改配置文件
const readAndModifyConfig = async () => {
    const projectName = inputProjectName;
    const path = `./${projectName}/package.json`;
    return new Promise((resolve, reject) => {
        fs.readFile(path, "utf-8", (error, data) => {
            if (error) {
                console.log("读取json配置文件失败：", error);
                return;
            }
            const jsonData = JSON.parse(data);
            // 修改package.json
            dependenciesList.forEach((item) => {
                jsonData.dependencies[item] = modulesObj[item];
            });
            devDependenciesList.forEach((item) => {
                jsonData.devDependencies[item] = modulesObj[item];
            });
            const updateData = JSON.stringify(jsonData, null, 2);
            fs.writeFile(path, updateData, "utf-8", (err) => {
                if (err) {
                    console.log("写入json配置文件失败：", err);
                    reject();
                    return;
                }
                // console.log("写入json配置文件成功");
                resolve();
            });
        });
    });
};
// clone项目
const cloneProject = async () => {
    const projectName = inputProjectName;
    const version = vueVersionFlag ? "cli-vue3" : "cli-vue2";
    const gitPath = `direct:https://gitee.com/wuhun1990/${version}.git#master`;
    const spinner = ora("正在下载模板...");
    const installModules = ora("node_modules安装中...");
    const typeData = {
        create: {
            type: "spinner",
            desc: "项目创建",
        },
        install: {
            type: "installModules",
            desc: "node_modules安装",
        },
        run: {
            type: "runProject",
            desc: "运行项目",
        },
    };
    try {
        // 拉取项目
        spinner.start();
        await new Promise((resolve, reject) => {
            download(gitPath, projectName, { clone: true }, (err) => {
                if (err) {
                    reject({
                        errorReason: err,
                        errorType: typeData.create,
                    });
                }
                resolve();
            });
        });
        // 修改配置文件
        await readAndModifyConfig();
        spinner.succeed("项目创建成功");
        // 适配window平台为npm.cmd
        const commandName = process.platform === "win32" ? "npm.cmd" : "npm";
        // install项目
        installModules.start();
        await execCommand(
            `${commandName} install`,
            { cwd: `./${projectName}` },
            typeData.install
        );
        installModules.succeed("node_modules安装成功");
        // 启动项目
        console.log(" 项目启动中...");
        await execCommand(
            `${commandName} run serve`,
            { cwd: `./${projectName}` },
            typeData.run
        );
    } catch (error) {
        if (error.errorReason) {
            const { errorReason, errorType } = error;
            const { type, desc } = errorType;
            if (type === "spinner") {
                spinner.fail(desc + "失败：" + errorReason);
            } else if (type === "installModules") {
                installModules.fail(desc + "失败，请手动安装：" + errorReason);
            } else if (type === "runProject") {
                console.log(desc + "失败：" + errorReason);
            }
        } else {
            console.log("捕获的未知错误：" + error);
        }
    }
};

// 监听输入的命令
// 创建项目
// program
//     .command("create <project-name>")
//     .description("创建项目")
//     .action(async function (projectName) {
//         queryProjectName(projectName);
//     });
// // 查询版本
// program.option("-v, --version", "查询版本").action(async function () {
//     const { version, author, updateTime } = cliData;
//     console.log("version：", version);
//     console.log("author：", author);
//     console.log("updateTime：", updateTime);
// });
// // 上传node_modules包
// program
//     .command("upload")
//     .description("上传node_modules包")
//     .action(function () {
//         console.log("此功能暂未开放，请耐心等待...");
//     });

// program.parse(process.argv);
export default queryProjectName;
